package cn.com.openportal.ffw.modules.sys.service.impl;

import cn.com.openportal.ffw.common.exception.RRException;
import cn.com.openportal.ffw.common.utils.BaseEntitySetValueUtils;
import cn.com.openportal.ffw.common.utils.Constant;
import cn.com.openportal.ffw.common.utils.PageUtils;
import cn.com.openportal.ffw.modules.sys.entity.SysUserEntity;
import cn.com.openportal.ffw.modules.sys.query.SysRoleQuery;
import cn.com.openportal.ffw.modules.sys.service.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.com.openportal.ffw.modules.sys.dao.SysRoleDao;
import cn.com.openportal.ffw.modules.sys.entity.SysRoleEntity;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 角色
 *
 * @author LeeSon
 */
@Service("sysRoleService")
public class SysRoleServiceImpl extends ServiceImpl<SysRoleDao, SysRoleEntity> implements SysRoleService {
    @Autowired
    private SysRoleMenuService sysRoleMenuService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysUserTokenService sysUserTokenService;
    @Autowired
    private BaseEntitySetValueUtils baseEntitySetValueUtils;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String roleName = (String) params.get("roleName");
        //Long createUserId = (Long) params.get("createUserId");
        List<Long> roleIds = (List<Long>) params.get("roleIds");
        if (null != roleIds) {
            if (roleIds.size() == 0) {
                roleIds.add(0L);
            }
        }

        IPage<SysRoleEntity> page = this.page(
                new SysRoleQuery().getPage(params),
                new QueryWrapper<SysRoleEntity>()
                        .like(StringUtils.isNotBlank(roleName), "role_name", roleName)
                        //.eq(createUserId != null, "create_user_id", createUserId)
                        .in(null != roleIds && roleIds.size() > 0, "role_id", roleIds)
        );

        PageUtils resultPage = new PageUtils(page);

        List<SysRoleEntity> list = (List<SysRoleEntity>) resultPage.getList();
        baseEntitySetValueUtils.BaseEntitySetValue(list);

        return resultPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveRole(SysRoleEntity role) {
        role.setCreateTime(new Date());
        this.save(role);

        //检查权限是否越权
        checkPrems(role);

        //保存角色与菜单关系
        sysRoleMenuService.saveOrUpdate(role.getRoleId(), role.getMenuIdList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SysRoleEntity role) {
        this.updateById(role);

        //检查权限是否越权
        checkPrems(role);

        //更新角色与菜单关系
        sysRoleMenuService.saveOrUpdate(role.getRoleId(), role.getMenuIdList());

        List<Long> userIds = new ArrayList<>();
        List<Long> t_userIds = sysUserRoleService.queryUserIdList(role.getRoleId());
        for (Long userId : t_userIds) {
            if (!userIds.contains(userId)) {
                userIds.add(userId);
            }
        }
        for (Long userId : userIds) {
            sysUserTokenService.logout(userId);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(Long[] roleIds) {
        //删除角色
        this.removeByIds(Arrays.asList(roleIds));

        //删除角色与菜单关联
        sysRoleMenuService.deleteBatch(roleIds);

        //删除角色与用户关联
        sysUserRoleService.deleteBatch(roleIds);

        List<Long> userIds = new ArrayList<>();
        for (Long roleId : roleIds) {
            List<Long> t_userIds = sysUserRoleService.queryUserIdList(roleId);
            for (Long userId : t_userIds) {
                if (!userIds.contains(userId)) {
                    userIds.add(userId);
                }
            }
        }
        for (Long userId : userIds) {
            sysUserTokenService.logout(userId);
        }
    }


    @Override
    public List<Long> queryRoleIdList(Long createUserId) {
        return baseMapper.queryRoleIdList(createUserId);
    }

    /**
     * 检查权限是否越权
     */
    private void checkPrems(SysRoleEntity role) {
        //如果不是超级管理员，则需要判断角色的权限是否超过自己的权限
        if (getUserId() == Constant.SUPER_ADMIN) {
            return;
        }

        //查询用户所拥有的菜单列表
        //List<Long> menuIdList = sysUserService.queryAllMenuId(role.getCreateUserId());
        List<Long> menuIdList = sysUserService.queryAllMenuId(getUserId());
        menuIdList.add(-666666L);

        //判断是否越权
        if (!menuIdList.containsAll(role.getMenuIdList())) {
            throw new RRException("角色的权限，已超出你的权限范围");
        }
    }

    private SysUserEntity getUser() {
        return (SysUserEntity) SecurityUtils.getSubject().getPrincipal();
    }

    private  Long getUserId() {
        return getUser().getUserId();
    }
}
